-- UICaptainDiary
-- Created by chengb Jan/20/2016
-- 舰长的日记界面

require "game/ui/form/sky_city/UISkyInstanceInfo"

UICaptainDiary = class("UICaptainDiary", function()
    return cc.Layer:create();
end);

function UICaptainDiary.create()
    return UICaptainDiary.new();
end

-- 标签页定义
local PAGE_UNCOMPLETED  = 1;   -- 未通关
local PAGE_COMPLETED    = 2;   -- 已完成

-- 所有的标签页
local ALL_PAGES = { PAGE_UNCOMPLETED, PAGE_COMPLETED };

-- 内部函数声明
local sortInstanceList;

-- 构造函数
function UICaptainDiary:ctor()
    self:setName("UICaptainDiary");

    -- 初始化
    local node = cc.CSLoader:createNode("layout/sky_city/CaptainDiary.csb");
    self:addChild(node);
    self.node = node;

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    self:init();

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();
end

-- 初始化
function UICaptainDiary:init()
    -- 标签页标题
    TAB_NAME_MAP = {
        [PAGE_UNCOMPLETED] = getLocStr("unpassed"),
        [PAGE_COMPLETED]   = getLocStr("completed"),
    };

    -- 默认选择第一个标签
    self.pageType = ALL_PAGES[1];

    -- 初始化副本列表数据
    self:initInstanceData();

    self.tabs = {};
    for i = 1, #ALL_PAGES do
        local tabNode  = findChildByName(self.node, "CT/tab/tab"..i);

        table.insert(self.tabs, tabNode);

        -- 为每个标签绑定类型
        local icon = findChildByName(tabNode, "icon");
        icon.pageType = ALL_PAGES[i];
    end

    -- 记录滚动容器原始宽高
    -- 切换标签页时，滚动容器的内部滚动区域可能会发生变化，因此这里需要将原始宽高记录下来
    local scrollview = findChildByName(self.node, "CT/scrollview");
    scrollview.initInnerHeight = scrollview:getInnerContainerSize().height;
    scrollview.initInnerWidth  = scrollview:getInnerContainerSize().width;
    self.scrollview = scrollview;

    for i = 1, #self.tabs do
        local tab = self.tabs[i];
        tab:setPositionY(tab:getPositionY() + 100);
    end

    -- tab的动画效果
    performWithDelay(self, function() self:playTabEffect(); end, 0.2);
end

--------------------------------------
-- 对副本进行排序
-- @param srcList       未排序的副本列表
-- @param exploredList  已出现在雷达上的副本列表
function sortInstanceList(srcList, exploredList)
    -- 排序规则：优先按照priority排，priority相同时再按照id排
    local function sortFunc(info1, info2)
        if info1.priority == info2.priority then
            return info1.dungeonId < info2.dungeonId;
        else
            return info1.priority > info2.priority;
        end
    end

    local tempList = {};
    for _, dungeonId in pairs(srcList) do
        local info = {};
        info.dungeonId = dungeonId;

        -- 未出现在雷达上的副本要排在前面
        if table.indexOf(exploredList, dungeonId) == -1 then
            info.priority = 1;
        else
            info.priority = 0;
        end
        table.insert(tempList, info);
    end
    table.sort(tempList, sortFunc);

    local dstList = {};
    for _, info in pairs(tempList) do
        table.insert(dstList, info.dungeonId);
    end

    return dstList;
end

-- 初始化副本数据
function UICaptainDiary:initInstanceData()
    -- 已出现在雷达上的副本列表
    local exploredList = SkyInstanceM.getExploredInstances();
    self.exploredList = exploredList;

    -- 未通关副本列表
    local unpassedList = SkyInstanceM.getUnpassedSkyInstances();
    self.unpassedList = sortInstanceList(unpassedList, exploredList);

    -- 已通关副本列表
    local passedList = SkyInstanceM.getPassedSkyInstances();
    self.passedList = sortInstanceList(passedList, exploredList);
end

-- 页签动画效果
function UICaptainDiary:playTabEffect()
    -- 待窗口动画播放结束后，页签从上面往下掉
    playTabEffect(self.tabs);
end

-- 适配
function UICaptainDiary:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 获取副本列表
function UICaptainDiary:getInstanceList()
    if self.pageType == PAGE_UNCOMPLETED then
        -- 未通关
        return self.unpassedList;
    else
        -- 已通关
        return self.passedList;
    end
end

-- 重绘
function UICaptainDiary:redraw()
    -- 显示标题
    local titleLabel = findChildByName(self.node, "CT/title");
    TextStyleM.setTextStyle(titleLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_ORANGE, true, -4, nil, nil, nil, nil, true);
    titleLabel:setString(getLocStr("captain_diary"));

    -- 显示日期
    local dateLabel = findChildByName(self.node, "CT/date");
    TextStyleM.setTextStyle(dateLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_DARK_BROWN);
    local dateStr = os.date("%b.%d", os.time());
    dateLabel:setString(dateStr);

    -- 显示描述
    local descLabel = findChildByName(self.node, "CT/desc");
    TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_DARK_BROWN);

    -- 获取最近一次修理飞艇的时间
    local lastRepaireTime = NewAirShipM.getLastRepairTime();
    local curTime = TimeM.getServerTime();
    local diffTime = curTime - lastRepaireTime;
    local day  = math.modf(diffTime / 86400);
    local hour = math.modf((diffTime % 86400)/3600);
    local timeStr = "";

    if day > 0 then
        timeStr = timeStr .. string.format(getLocStr("reset_days"), day);
    end

    if hour > 0 then
        timeStr = timeStr .. string.format(getLocStr("reset_hour"), hour);
    else
        timeStr = timeStr .. string.format(getLocStr("reset_hour"), 1);
    end

    local desc = string.format(getLocStr("captain_diary_desc"), timeStr);

    applyString(descLabel, desc);

    -- 重绘标签页
    self:redrawTabs();

    -- 重绘副本列表
    self:redrawInstanceList();
end

-- 注册事件处理回调函数
function UICaptainDiary:registerEventCallback()
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            cclog("UICaptainDiary 界面析构清理");
        end
    end);
end

-- 重绘副本列表
function UICaptainDiary:redrawInstanceList()
    local scrollview = self.scrollview;
    scrollview:removeAllChildren();
    scrollview:jumpToTop();

    local itemNode = cc.CSLoader:createNode("layout/sky_city/SkyInstanceItem.csb");

    -- 单元格间距(横向)
    local wGap = 0;

    -- 单元格间距(纵向)
    local hGap = 0;

    -- 单元格宽度
    local itemWidth = 0;

    -- 单元格高度
    local itemHeight = 61;

    -- 左右留白
    local leftMargin = 1;

    -- 上方留白
    local topMargin = 10;

    -- 下方留白
    local bottomMagin = 0;

    -- 单页最大可容纳行数
    local pageRowNum = 7;

    -- 单页最大可容纳列数
    local pageColNum = 1;

    -- 获取该页的副本列表
    self.instanceList = self:getInstanceList();

    -- 获取记录总数
    local totalNum = #self.instanceList;

    -- 初始化滚动容器
    ScrollTool.initScrollGridsVertical(self, scrollview, itemNode, totalNum,
        pageColNum, wGap, hGap,
        itemWidth, itemHeight, topMargin, bottomMagin, leftMargin,
        self.registerItemTouchEvent, self.initInstanceItem);

    -- 如果超过一页
    if totalNum > pageRowNum then
        -- 添加滑块
        UIIndicator.attach(scrollview);
    end
end

-- 注册滚动容器每一行被点击的事件
function UICaptainDiary:registerItemTouchEvent(node)
    local touchImg = findChildByName(node, "touch_bg");
    touchImg:setOpacity(0);
    local function onBgClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            self:onChildClick(node);
            AudioM.playFx("button_caption");
        end
    end
    touchImg:addTouchEventListener(onBgClick);
end

-- 副本被点击的处理
function UICaptainDiary:onChildClick(child)
    local dungeonId = child.dungeonId;

    -- 显示副本信息
    local uiForm = UISkyInstanceInfo.create(dungeonId);
    UIMgr.getCurrentScene():removeFormByName("UISkyInstanceInfo");
    UIMgr.getCurrentScene():addForm(uiForm);
end

-- 初始化副本项
function UICaptainDiary:initInstanceItem(child, index)
    local dungeonId = self.instanceList[index];
    child.dungeonId = dungeonId;

    local iconImg = findChildByName(child, "icon");
    local goImg   = findChildByName(child, "go");
    local statusLabel = findChildByName(child, "status");
    local descLabel = findChildByName(child, "desc");

    if table.indexOf(self.exploredList, dungeonId) ~= -1 then
        -- 已出现在雷达上

        iconImg:loadTexture("images/ui/sky_city/instance_island.png");

        -- 描述需要显示绿色
        TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_GREEN);

        -- 显示已出现
        goImg:setVisible(false);
        statusLabel:setVisible(true);
        TextStyleM.setTextStyle(statusLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_GRAY);
        statusLabel:setString(getLocStr("appeared"));
    else
        -- 未出现在雷达上

        iconImg:loadTexture("images/ui/sky_city/instance_map.png");

        TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN);

        -- 显示"前往"图标
        goImg:setVisible(true);
        statusLabel:setVisible(false);

        goImg:setSwallowTouches(true);

        -- 注册"前往"图标点击事件
        goImg:setTouchEnabled(true);
        local function onGoClick(sender, eventType)
            if eventType == ccui.TouchEventType.began then
                goImg:setScale(0.9);
            elseif eventType == ccui.TouchEventType.ended then
                goImg:setScale(1.0);

                local title = DungeonAreaM.query(dungeonId, "name");

                -- 需求雷达能量
                local requireEnergy = SkyInstanceM.calcExploreCostEnergy(dungeonId);

                -- 当前雷达能量
                local curEnergy = ME.user.dbase:query("ship_energy", 0);

                local isEnough = iif(curEnergy >= requireEnergy, true, false);

                local function doExplore()
                    if not isEnough then
                        -- 能量不足
                        -- alert(getLocStr("airship_select_no_energy"));
                        showEnergyLackConfirm();
                        return;
                    end

                    -- 执行探索
                    SkyInstanceM.doExplore(dungeonId);
                    closeFormByName("UISkyResource");
                    closeFormByName(self:getName());
                end

                -- 能量不足时需要显示红色
                local curEnergyStr = "";
                if isEnough then
                    curEnergyStr = string.format("[blue]%d[-]", curEnergy);
                else
                    curEnergyStr = string.format("[red]%d[-]", curEnergy);
                end

                local content = string.format(getLocStr("record_sky_instance"), requireEnergy, curEnergyStr);

                confirm2(CONFIRM_TYPE_OK_CANCEL, title, content, doExplore);
            end
        end
        goImg:addTouchEventListener(onGoClick);
    end

    -- 副本名称和最高层数
    local name = DungeonAreaM.query(dungeonId, "name");
    local maxLayer = DungeonAreaM.query(dungeonId, "max_floor") or 0;
    local desc = string.format(getLocStr("sky_instance_name"), name, maxLayer);
    descLabel:setString(desc);

    -- 如果是第一条记录，需要显示上部的分隔线
    local lineTop = findChildByName(child, "line2");
    if index == 1 then
        lineTop:setVisible(true);
    else
        lineTop:setVisible(false);
    end

    return child;
end

-- 注册点击事件
function UICaptainDiary:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UICaptainDiary");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册各个标签页点击事件
    for _, tabNode in pairs(self.tabs) do
        local iconImg = findChildByName(tabNode, "icon");
        local function onTabClick(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                self.pageType = sender.pageType;

                -- 重绘界面
                self:redraw();

                AudioM.playFx("button_spell");
            end
        end
        iconImg:addTouchEventListener(onTabClick);
    end
end

-- 重绘标签页
function UICaptainDiary:redrawTabs()
    for _, tabNode in pairs(self.tabs) do
        local iconImg   = findChildByName(tabNode, "icon");
        local lightImg = findChildByName(tabNode, "light");
        local titleLabel = findChildByName(tabNode, "title");
        local pageType = iconImg.pageType;

        TextStyleM.setOutlineStyle(titleLabel, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);
        TextStyleM.setTextStyle(titleLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -3);

        titleLabel:setString(TAB_NAME_MAP[pageType]);
        local normalColor = TextStyleM.TEXT_COLOR_NORMAL;
        local blendColor  = TextStyleM.TEXT_COLOR_BLEND;

        if self.pageType == pageType then
            -- 被选中的标签高亮显示
            lightImg:setVisible(true);
            iconImg:setHighlighted(true);
            iconImg:setTouchEnabled(false);
            iconImg:setColor(normalColor);
            titleLabel:setColor(normalColor);
        else
            lightImg:setVisible(false);
            iconImg:setHighlighted(false);
            iconImg:setTouchEnabled(true);
            iconImg:setColor(blendColor);
            titleLabel:setColor(blendColor);
        end
    end
end
